package proyectobdii;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.LinkedList;

public class Report_Manager {
    public static String BASE = (new java.io.File("")).getAbsolutePath();
    
    
    public Report_Manager(Diff_Procedure diff_procedure, Diff_Tables diff_tables) throws IOException {
        if (CreateFile("Report")) {
            System.out.println("El archivo se ha creado exitosamente.");
            PrintDiff(diff_procedure, diff_tables, "Report", "gedit");
        }
        else
            System.out.println("Error al crear el archivo. Intente nuevamente.");
    }
    
    /**
     Realiza la creación de un archivo, el cual tendrá como nombre el string que recibe como
     * parametro. Devuelve false en caso de que se produzca un error durante la creacion
     * de tal archivo.
     */
    private boolean CreateFile (String file_name) throws IOException {
        File archivo = new File(file_name + ".txt");
        if(!archivo.exists()){
            if(archivo.createNewFile())
                return true;
        }
        return false;
    }
    
    /**
     Imprime la información que posee la base de datos que recibe como parámetro. Tal información
     * es almacenada en un archivo llamado Report.txt, el cual contendrá toda la información de las
     * tablas de dicha base de datos.
     */
    private void PrintDiff (Diff_Procedure diff_procedure, Diff_Tables diff_tables, String file_name, String editor) throws IOException {
        FileWriter fw = new FileWriter(file_name + ".txt");
        BufferedWriter bw = new BufferedWriter(fw);
        PrintWriter output = new PrintWriter(bw);
        
        output.print("Comparación estructural de dos Bases de Datos\n\n");
        
        String out_text = "Nombre de la Base de Datos: "+diff_tables.getNombreDataBase(1);
        output.print(out_text);
        
        output.print(PrintTables(diff_tables.getExclusiveTablesDBI()));
        out_text = "1) Tablas propias: "+diff_tables.getNombreDataBase(0)+"\n";
        output.print(out_text);
        output.print(PrintTables(diff_tables.getExclusiveTablesDBII()));

        out_text = "2) Tablas comunes: \n";
        output.print(out_text);
        output.print(PrintTables(diff_tables.getCommonTables()));

        output.print("3) Diferencias entre tablas con el mismo nombre: \n");
        output.print(PrintEqualsTables(diff_tables));
            
        output.print("4) Procedures propios: "+diff_procedure.getNombreDataBase(1)+"\n\n");
        output.print(PrintProcedures(diff_procedure.getExclusiveProcedureDBI()));
 
        output.print("5) Procedures propios de la base de datos: "+diff_procedure.getNombreDataBase(2)+"\n");
        output.print(PrintProcedures(diff_procedure.getExclusiveProcedureDBII()));
        
        output.print("6) Procedures comunes en ambas bases de datos: \n");
        output.print(PrintProcedures(diff_procedure.getCommonProcedure()));
        
        output.print("7) Diferencias de Procedures con el mismo nombre: \n\n");
        output.print(ProceduresMismoNombre(diff_procedure));

        output.close();
        String PATH_SOURCE_TXT = BASE +"/"+file_name+".txt";
        System.out.println(PATH_SOURCE_TXT);
        Creacion_Exitosa crea = new Creacion_Exitosa();
        crea.setText(PATH_SOURCE_TXT);
        crea.setVisible(true);
    }

    private String PrintTables(LinkedList<Table> listaTablas) {
        String out = new String();
        for (int i = 0; i < listaTablas.size(); i++) {
            Table tabla = listaTablas.get(i);
            out = out+"Nombre: "+tabla.getNombre()+", ";
            out = out+"PK: "+tabla.getPk()+".\n";
            out = out+"Columnas: ";
            LinkedList<Parameter> listaColumnas = tabla.getColumnas();
      
            for (int j = 0; j < listaColumnas.size(); j++) {
                Parameter parametro = listaColumnas.get(j);
                out = out+parametro.toString()+" ";
            }
            
            out = out + "\n\n";
            out = out+"Indices: ";
            LinkedList<Index> listaIndex = tabla.getIndex();
            for (int k = 0; k < listaIndex.size(); k++) {
                Index indexAux = listaIndex.get(k);
                out = out+indexAux.toString()+" ";
            }
            out = out + "\n\n";
        }
        return out;
    }

    private String PrintEqualsTables(Diff_Tables diff_tables) {
        LinkedList<Table> tablasComunes = diff_tables.getDifferentTables();
        String out="";
        for(int i=0;i<tablasComunes.size();i=i+2){
            Table tabla = tablasComunes.get(i);
            Table tabla2 = tablasComunes.get(i+1);
            out+="Nombre: "+tabla.getNombre()+"\n";
            out+="Clave primaria 1: "+tabla.getPk()+"\t"+"Clave primaria 2: "+tabla2.getPk()+"\n";
            out+="Unique 1: "+tabla.getUniques().toString()+"\t" + "Unique 2" +tabla2.getUniques().toString()+"\n";
            out+="Columnas 1: "+tabla.getColumnas().toString()+"\n";
            out+="Columnas 2: "+tabla2.getColumnas().toString()+"\n";
            out+="Triggers 1: "+tabla.getTriggers().toString()+"\n";
            out+="Triggers 2: "+tabla2.getTriggers().toString()+"\n";
            out+="\n";
        }
        return out;
    }

    private String PrintProcedures(LinkedList<Procedure> listaProcedure){
        String Procedures = new String();
        for (int i = 0; i < listaProcedure.size(); i++) {
            Procedure Procedure = listaProcedure.get(i);
            Procedures = Procedures+"Nombre: "+Procedure.getNombre();
            Procedures = Procedures+" ,Retorna: "+Procedure.getTipo();
            Procedures = Procedures+" ,Parametros: ";
            LinkedList<Parameter> listaParametros = Procedure.getParametros();
            for (int j = 0; j < listaParametros.size(); j++) {
                Parameter parametro = listaParametros.get(j);
                Procedures = Procedures+parametro.toString()+" ";
            }
            Procedures = Procedures + "\n\n";
        }
        return Procedures;
    }

    private String ProceduresMismoNombre(Diff_Procedure diff_procedure) {
        LinkedList<Procedure> ProceduresComunes = diff_procedure.getDifferentProcedure();
        String out="";
        for(int i=0;i<ProceduresComunes.size()/2;i++) {
            Procedure procedure = ProceduresComunes.get(i);
            Procedure procedure2 = ProceduresComunes.get(i+1);
            out+="Nombre: "+procedure.getNombre()+"\n";
            out+="Retorna 1: "+procedure.getTipo()+"\t"+"Retorna 2: "+procedure2.getTipo()+"\n";
            out+="Parametros 1: "+procedure.getParametros().toString()+"\t";
            out+="Parametros 2: "+procedure2.getParametros().toString()+"\n";
            out+="\n";
        }
        return out;
    }
}